{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "private_outputs": true,
      "provenance": [],
      "collapsed_sections": [
        "sDysIMXLmJhs"
      ],
      "gpuType": "T4",
      "cell_execution_strategy": "setup",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a target=\"_blank\" href=\"https://colab.research.google.com/github/TavernAI/TavernAI/blob/main/colab/TAI%E2%99%A5KCpp_RC_3.0.ipynb\"><img src=\"https://www.tavernai.xyz/oic.png\" alt=\"Open In Colab\"><br>Open in Colab</a>"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# @title { run: \"auto\", form-width: \"125%\", display-mode: \"form\" }\n",
        "#@markdown\n",
        "!!rm -rf /content/sample_data/\n",
        "!!sudo apt install aria2 -y\n",
        "!!wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb\n",
        "!!sudo dpkg -i cloudflared-linux-amd64.deb\n",
        "from google.colab import output\n",
        "# ♫♪ There's something happening here. ♫♪\n",
        "from IPython.core.display import display, HTML\n",
        "# ♫♪ But what it is ain't exactly clear... ♫♪\n",
        "from google.colab.output import clear\n",
        "# ♫♪ There's a man and a nun over there??? ♫♪\n",
        "class InvokeButton1(object):\n",
        "  def __init__(self, title, callback):\n",
        "    self._title = title\n",
        "    self._callback = callback\n",
        "  def _repr_html_(self):\n",
        "    callback_id = 'button1'\n",
        "    output.register_callback(callback_id, self._callback)\n",
        "    template = \"\"\"<button id=\"{callback_id}\">{title}</button>\n",
        "        <script>\n",
        "          document.querySelector(\"#{callback_id}\").onclick = (e) => {{\n",
        "            google.colab.kernel.invokeFunction('{callback_id}', [], {{}})\n",
        "            e.preventDefault();\n",
        "          }};\n",
        "        </script>\"\"\"\n",
        "    html = template.format(title=self._title, callback_id=callback_id)\n",
        "    return html\n",
        "# ♫♪ Throwing cheese... ♫♪ up in the air!?! ♫♪\n",
        "def user_pulled_a_henky():\n",
        "    output.clear(output_tags='F5')\n",
        "    with output.use_tags(tags='F5'):\n",
        "        display(HTML('<audio autoplay=\"\" src=\"https://tavernai.xyz/silence.m4a\" loop>'))\n",
        "# ♫♪ I think it's time we: ♫♪ STOP. ♫♪\n",
        "with output.use_tags(tags='F5'):\n",
        "    display(HTML('<audio autoplay=\"\" src=\"https://tavernai.xyz/silence.m4a\" loop>'))\n",
        "# ♫♪ Colab, ♫♪ what's that sound? ♫♪\n",
        "InvokeButton1(\"Henky's button.\", user_pulled_a_henky)\n",
        "# ♫♪ Nobody gonna see ♫♪ what's going down... ♫♪\n",
        "# --FunkEngine"
      ],
      "metadata": {
        "id": "IBthvEFCmGbU"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "P5tgPblOlsbq"
      },
      "outputs": [],
      "source": [
        "# @title # TavernAI { form-width: \"110%\", display-mode: \"form\" }\n",
        "# FunkEngine's implementation ©\n",
        "use_google_drive = True #@param {type:\"boolean\"}\n",
        "# @markdown # THIS IS A PUBLIC Release Candidate extended Beta! Use GPU.ipynb if you're wondering \"How does I Tavern?\"\n",
        "# @markdown # You run this TavernAI cell __FIRST__. Same as the old 'GPU.ipynb', but different.\n",
        "ale_cellar = False # @param {type:\"boolean\"}\n",
        "needle = ''\n",
        "tavetoke = ''\n",
        "!!rm -rf /content/sample_data/\n",
        "import os\n",
        "import time\n",
        "import requests\n",
        "import IPython\n",
        "import IPython.display\n",
        "from IPython.core.display import display, HTML\n",
        "from google.colab import runtime\n",
        "from google.colab import output\n",
        "os.chdir('/')\n",
        "if use_google_drive:\n",
        "  from google.colab import drive\n",
        "  drive.mount('/content/drive', force_remount=True)\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI\"):\n",
        "    os.mkdir(\"/content/drive/MyDrive/TavernAI\")\n",
        "else:\n",
        "  if not os.path.exists(\"/content/drive\"):\n",
        "    os.mkdir(\"/content/drive\")\n",
        "  if not os.path.exists(\"/content/drive/MyDrive\"):\n",
        "    os.mkdir(\"/content/drive/MyDrive\")\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI\"):\n",
        "    os.mkdir(\"/content/drive/MyDrive/TavernAI\")\n",
        "\n",
        "#↓↓↓↓Versions↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "os.chdir('/')\n",
        "print(\"Debug Info Below.\")\n",
        "!node -v\n",
        "!npm -v\n",
        "!cloudflared -v\n",
        "print(\"Debug Info above.\")\n",
        "\n",
        "#↓↓↓↓n00b-chk↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "if os.path.exists(\"/content/TavernAI\"):\n",
        "    print(\"Be careful! You're re-running TavernAI!\")\n",
        "    print(\"\")\n",
        "    print(\"DO YOU ACTUALLY KNOW WHAT YOU ARE DOING?\")\n",
        "    print(\"\")\n",
        "    print(\"YES or NO?\")\n",
        "    sussyaf = str(input(\"Type YES or NO:\"))\n",
        "    if sussyaf != 'YES' and sussyaf != 'NO':\n",
        "        print(\"That was a YES or NO question...\")\n",
        "        print(\"\")\n",
        "        print(sussyaf)\n",
        "        print(\"\")\n",
        "        print(\"Is neither. Calm down or pay closer attentiom when you try again....\")\n",
        "        print(\"Lets start over fresh.\")\n",
        "        print(\"\")\n",
        "        print(\"Refresh this page and try again, ENDING Runtime --FunkEngine\")\n",
        "        runtime.unassign()\n",
        "    if sussyaf == 'NO':\n",
        "        print(\"Thank you for your honesty.\")\n",
        "        print(\"If you were attempting to \\\"Start Over\\\"\")\n",
        "        print(\"Because something went wrong...\")\n",
        "        print(\"Colab is a machine in the cloud, not a website on your screen.\")\n",
        "        print(\"Refreshing the page does not reboot the machine, nor closing the tab end the runtime immediately.\")\n",
        "        print(\"To FULLY RESTART a colab session, AKA Starting-Fresh:\")\n",
        "        print(\"Up above in the menu bar...\")\n",
        "        print(\"\")\n",
        "        print(\"\")\n",
        "        print(\"\")\n",
        "        display(IPython.display.HTML('<video autoplay=\"\" src=\"https://funkengine.me/lot2learn.mp4\" controls>'))\n",
        "        print(\"\")\n",
        "        print(\"\")\n",
        "        print(\"\")\n",
        "        print(\"You want to choose Runtime -> Disconnect and Delete Runtime\")\n",
        "        print(\"THEN you can run things again, optionally refreshing the page if maybe you fiddled with something you weren't supposed to touch...\")\n",
        "        print(\"I am going to END this runtime FOR you NOW... Mostly because you were honest about not knowing what you were doing.\")\n",
        "        print(\"If you poked something you shouldn't have I suggest refreshing the page before you fire things back up.\")\n",
        "        print(\"--FunkEngine\")\n",
        "        runtime.unassign()\n",
        "    if sussyaf == 'YES':\n",
        "        print(\"Are you sure about that?\")\n",
        "        print(\"Because I'm not sure I believe you...\")\n",
        "        print(\"About actually knowing what you're doing right now.\")\n",
        "        sure = str(input(\"Are you REALLY SURE? YES or NO\"))\n",
        "        if sure != 'YES' and sure != 'NO':\n",
        "            print(sure)\n",
        "            print(\"Woah there buddy! That was a YES or NO question!\")\n",
        "            print(\"Ending Runtime.\")\n",
        "            runtime.unassign()\n",
        "        if sure == \"NO\":\n",
        "            print(\"You shouldn't have been so sussy about it.\")\n",
        "            print(\"I asked if you knew what yuo were doing and you said: \" + sussyaf + \"But when I called your bluff you said: \" + sure)\n",
        "            print(\"You're still learning how all this AI stuff works.\")\n",
        "            print(\"There's a WHOLE LOT to learn, and it takes MONTHS just to stop feeling like a complete n00b.\")\n",
        "            print(\"Relax. You'll get there.\")\n",
        "            import IPython.display\n",
        "            display(IPython.display.HTML('<video autoplay=\"\" src=\"https://funkengine.me/lot2learn.mp4\">'))\n",
        "            print(\"I'll help you out and start you over fresh.\")\n",
        "            print(\"Please refresh this browser tab and have another go.\")\n",
        "            print(\"Ending the Colab Runtime for you now.\")\n",
        "            runtime.unassign()\n",
        "        if sure == 'YES' and sussyaf == 'YES':\n",
        "            print(\"I still don't believe you but whatever.\")\n",
        "            print(\"YOLO\")\n",
        "            print(\"--FunkEngine\")\n",
        "\n",
        "#↓↓↓↓TAI-REPO↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "print(\"Acquiring TavernAI from the GitHub Repo!\")\n",
        "if not os.path.exists(\"/content/TavernAI\"):\n",
        "  os.mkdir(\"/content/TavernAI\")\n",
        "  !!git clone -b main https://github.com/TavernAI/TavernAI/ /content/TavernAI/\n",
        "time.sleep(1)\n",
        "\n",
        "#↓↓↓↓NPM-INST↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "os.chdir('/content/TavernAI/')\n",
        "!!npm install\n",
        "time.sleep(1)\n",
        "\n",
        "#↓↓↓↓Persistence↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "if use_google_drive:\n",
        "  print(\"TavernAI 'Total User eXpericnce Persistence'\")\n",
        "  print(\"Courtesy of --FunkEngine!\")\n",
        "  print(\"Starting with User Avatars...\")\n",
        "  os.chdir('/')\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI/User Avatars\"):\n",
        "    print(\"Setting up Google Drive to hold avatars.\")\n",
        "    !!mv -v '/content/TavernAI/public/User Avatars' '/content/drive/MyDrive/TavernAI/'\n",
        "  os.chdir('/')\n",
        "  if os.path.exists(\"/content/drive/MyDrive/TavernAI/User Avatars\") and not os.path.islink(\"/content/TavernAI/public/User Avatars\"):\n",
        "    print(\"Using existing avatars from your Google Drive new avatars stored as well.\")\n",
        "    !!rm -rf '/content/TavernAI/public/User Avatars'\n",
        "    !!ln -fs '/content/drive/MyDrive/TavernAI/User Avatars/' '/content/TavernAI/public/'\n",
        "    os.chdir('/')\n",
        "    print(\"Avatars shall persist between sessions.\")\n",
        "  if not os.path.isfile(\"/content/drive/MyDrive/TavernAI/settings.json\"):\n",
        "    print(\"First time here? Copying default settings for you so they persist when you change them...\")\n",
        "    !!cp -f -p \"/content/TavernAI/public/settings.json\" \"/content/drive/MyDrive/TavernAI/settings.json\"\n",
        "    os.chdir('/')\n",
        "  if os.path.isfile(\"/content/drive/MyDrive/TavernAI/settings.json\") and not os.path.islink(\"/content/TavernAI/public/settings.json\"):\n",
        "    print(\"Linking settings from your Google Drive to be used instead of defaults.\")\n",
        "    !!rm -f \"/content/TavernAI/public/settings.json\"\n",
        "    !!ln -fs \"/content/drive/MyDrive/TavernAI/settings.json\" \"/content/TavernAI/public/settings.json\"\n",
        "    os.chdir('/')\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI/characters\"):\n",
        "    print(\"Setting up Google Drive to hold character cards.\")\n",
        "    !!mv -v /content/TavernAI/public/characters /content/drive/MyDrive/TavernAI/\n",
        "    os.chdir('/')\n",
        "  if os.path.exists(\"/content/drive/MyDrive/TavernAI/characters\") and not os.path.islink(\"/content/TavernAI/public/characters\"):\n",
        "    print(\"Using existing characters from your Google Drive new characters will be stored there as well.\")\n",
        "    !!rm -rf /content/TavernAI/public/characters\n",
        "    !!ln -fs /content/drive/MyDrive/TavernAI/characters/ /content/TavernAI/public/\n",
        "    os.chdir('/')\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI/rooms\"):\n",
        "    print(\"More people more fun, right? Setting up Google Drive to also manage your rooms.\")\n",
        "    !!mv -v /content/TavernAI/public/rooms /content/drive/MyDrive/TavernAI/\n",
        "    os.chdir('/')\n",
        "  if os.path.exists(\"/content/drive/MyDrive/TavernAI/rooms\") and not os.path.islink(\"/content/TavernAI/public/rooms\"):\n",
        "    print(\"Bringing in your multiplayer rooms from Google Drive. Try not to have too much fun!\")\n",
        "    !!rm -rf /content/TavernAI/public/rooms\n",
        "    !!ln -fs /content/drive/MyDrive/TavernAI/rooms/ /content/TavernAI/public/\n",
        "    os.chdir('/')\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI/chats\"):\n",
        "    print(\"Don't you rememeber what they took from us? Setting up Google Drive to remember the past.\")\n",
        "    !!mv -v /content/TavernAI/public/chats /content/drive/MyDrive/TavernAI/\n",
        "    os.chdir('/')\n",
        "  if os.path.exists(\"/content/drive/MyDrive/TavernAI/chats\") and not os.path.islink(\"/content/TavernAI/public/chats\"):\n",
        "    print(\"Using your conversation histories from Google Drive. Always remember what they took from us!\")\n",
        "    !!rm -rf /content/TavernAI/public/chats\n",
        "    !!ln -fs /content/drive/MyDrive/TavernAI/chats/ /content/TavernAI/public/\n",
        "    os.chdir('/')\n",
        "  if not os.path.exists(\"/content/drive/MyDrive/TavernAI/backgrounds\"):\n",
        "    print(\"I've heard talk that backgrounds are extremely super important to some of you... --FunkEngine\")\n",
        "    !!mv -v /content/TavernAI/public/backgrounds /content/drive/MyDrive/TavernAI/\n",
        "    os.chdir('/')\n",
        "  if os.path.exists(\"/content/drive/MyDrive/TavernAI/backgrounds\") and not os.path.islink(\"/content/TavernAI/public/backgrounds\"):\n",
        "    print(\"Bringing along the scenery as well...\")\n",
        "    !!rm -rf /content/TavernAI/public/backgrounds\n",
        "    !!ln -fs /content/drive/MyDrive/TavernAI/backgrounds/ /content/TavernAI/public/\n",
        "    print(\"Background storage linked!\")\n",
        "  print(\"That should be everything set up the way it was when you left the last time...\")\n",
        "  print(\"TavernAI user experience continuity is implied but not guaranteed.\")\n",
        "\n",
        "#↓↓↓↓-EPHEMERAL-↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "if not use_google_drive:\n",
        "  print(\"!!!!!!WARNING!!!!!\")\n",
        "  print(\"Ephemeral-Tavern engaged!!!\")\n",
        "  print(\"You chose not to use Google Drive.\")\n",
        "  print(\"Your Chats...\")\n",
        "  print(\"Your Cards...\")\n",
        "  print(\"Your Settings...\")\n",
        "  print(\"Will __NOT__ be saved!\")\n",
        "  print(\"Gone forever when this Colab runtime terminates.\")\n",
        "  print(\"Like Tears...\")\n",
        "  print(\"In the Rain...\")\n",
        "\n",
        "#↓↓↓↓ROLL-OUT↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "print(\"DONE!\")\n",
        "#LZ is CLEAR! We are GO for landing! (Landing a seat at the bar in the tavern, of course! This isn't actual rocket-science...)\n",
        "os.chdir('/content/TavernAI/')\n",
        "if ale_cellar:\n",
        "    from google.colab import userdata\n",
        "    print(\"Do you have tunnel infrastructure ready to use?\")\n",
        "    tavetoke = userdata.get('COLABTAVERNSEC')\n",
        "    if tavetoke != '':\n",
        "        print(\"It would seem you are on the upper end of the bell-curve...\")\n",
        "        os.chdir('/content/')\n",
        "        if not os.path.isfile('/content/cloudflared-linux-amd64.deb'):\n",
        "            !!wget https://github.com/cloudflare/cloudflared/releases/download/latest/cloudflared-linux-amd64.deb\n",
        "            time.sleep(1)\n",
        "            os.chmod('/content/cloudflared-linux-amd64.deb', 0o777)\n",
        "            print(\"Using provided token hashes to plumb into your tunnel infrastructure.\")\n",
        "            !!sudo dpkg -i cloudflared-linux-amd64.deb\n",
        "            print(\"Cloudflared installed properly, ready to deploy!\")\n",
        "        if tavetoke != '':\n",
        "            print(\"Looks like you have given us a token for tunneling the TavernAI instance out...\")\n",
        "            !!nohup cloudflared tunnel --no-autoupdate run --token $tavetoke &\n",
        "            print(\"Connector is up and running... For TavernAI...\")\n",
        "        print(\"Tunnels plumbed in should be good to go now...\")\n",
        "        os.chdir('/content/TavernAI/')\n",
        "        !!nohup node server.js > /content/drive/MyDrive/TavernAI/console.log 2>&1 &\n",
        "else:\n",
        "    os.chdir('/content/TavernAI/')\n",
        "    #print(\"Ask about the benefits of the ale_cellar club...  --FunkEngine.\")\n",
        "\n",
        "class InvokeButton3(object):\n",
        "  def __init__(self, title, callback):\n",
        "    self._title = title\n",
        "    self._callback = callback\n",
        "\n",
        "  def _repr_html_(self):\n",
        "    callback_id = 'button3'\n",
        "    output.register_callback(callback_id, self._callback)\n",
        "\n",
        "    template = \"\"\"<button id=\"{callback_id}\">{title}</button>\n",
        "        <script>\n",
        "          document.querySelector(\"#{callback_id}\").onclick = (e) => {{\n",
        "            google.colab.kernel.invokeFunction('{callback_id}', [], {{}})\n",
        "            e.preventDefault();\n",
        "          }};\n",
        "        </script>\"\"\"\n",
        "    html = template.format(title=self._title, callback_id=callback_id)\n",
        "    return html\n",
        "\n",
        "def do_something():\n",
        "    if needle != '':\n",
        "        print(\"This Cell == COMPLETE.\")\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "    print(\"If you didn't get links, CloudFlare is probably down at this time. Or you're using the ale_cellar secret tunnel.\")\n",
        "    return\n",
        "\n",
        "\n",
        "#↓↓↓↓STARTING↓↓↓↓\n",
        "#↓↓↓↓~TUNNEL~↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "#Cloudflared travel size secure egress tunnel deploying...\n",
        "if not ale_cellar:\n",
        "    os.chdir('/content/')\n",
        "    if not os.path.isfile('/content/cloudflared-linux-amd64.deb'):\n",
        "        !!wget https://github.com/cloudflare/cloudflared/releases/download/latest/cloudflared-linux-amd64.deb\n",
        "        time.sleep(1)\n",
        "        os.chmod('/content/cloudflared-linux-amd64.deb', 0o777)\n",
        "        print(\"Acquiring tunnel infrastructure.\")\n",
        "        !!sudo dpkg -i cloudflared-linux-amd64.deb\n",
        "        print(\"Cloudflared installed properly, ready to deploy!\")\n",
        "    !!nohup cloudflared tunnel --url http://127.0.0.1:8000 > cf.txt 2>&1 &\n",
        "    time.sleep(4)\n",
        "\n",
        "    #↓↓↓↓GET-LINK↓↓↓↓\n",
        "    #↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "    scrape = open('cf.txt', 'r')\n",
        "    haystack = scrape.read()\n",
        "    scrape.close()\n",
        "    scrape = ''\n",
        "    lodestone = haystack.split(\"  https://\")[1]\n",
        "    haystack = ''\n",
        "    needle = lodestone.split('.trycloudflare.com')[0]\n",
        "    lodestone = ''\n",
        "    needle = (\"https://\" + needle + \".trycloudflare.com/\")\n",
        "    #It's in here somewhere...\n",
        "    #Something sharp and pointy turned up...\n",
        "    #Lets see if we found what we need...\n",
        "    os.chdir('/content/')\n",
        "    if needle == 'https://.trycloudflare.com/':\n",
        "        needle = ''\n",
        "        #Once more, in case it didn't find it the first time...\n",
        "        print(\"Hang on, Cloudflare might be \\\"I am iz H4\\\\/InG t3h dUmb nA0!\\\" Since we didn't get our tunnel on the first attempt, going to try again but CF might be down at the moment...\")\n",
        "        #Give the connector a chance to back off and retry up to four times...\n",
        "        time.sleep(20)\n",
        "        #You doin okay lil buddy?\n",
        "        scrape = open('cf.txt', 'r')\n",
        "        #Heloooooo?\n",
        "        haystack = scrape.read()\n",
        "        #Looking for a Zero-Trust quick-tunnel...\n",
        "        scrape.close()\n",
        "        scrape = ''\n",
        "        lodestone = haystack.split(\"  https://\")[1]\n",
        "        haystack = ''\n",
        "        needle = lodestone.split('.trycloudflare.com')[0]\n",
        "        lodestone = ''\n",
        "        needle = (\"https://\" + needle + \".trycloudflare.com/\")\n",
        "        #Anybody there?...\n",
        "        #Lets see if we found what we need...\n",
        "        if needle == 'https://.trycloudflare.com/':\n",
        "            needle = ''\n",
        "            print(\"CLOUDFLARE QUICK TUNNEL FAILED TO DO ITS ONE BLEEDIN JOB!\")\n",
        "            print(\"CLOUDFLARE ZERO TRUST TUNNELS MAY BE DOWN RIGHT NOW.\")\n",
        "            print(\"Check https://www.cloudflarestatus.com/ and see if there are any open incidents...\")\n",
        "            print(\"If there are and any of them mention Zero-Trust Tunnels or just Tunnels in general:\")\n",
        "            print(\"Then TUNNELS are DOWN / Cloudflare is DOWN.\")\n",
        "            print(\"There is nothing wrong with TavernAI, this is not a bug!\")\n",
        "            print(\"There's essentially nothing you can do about it but wait, really...\")\n",
        "\n",
        "#↓↓↓↓RIDE|DIE↓↓↓↓\n",
        "#↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "#It's Ride or Die time boys and girls!!!\n",
        "if needle == '' and not ale_cellar:\n",
        "    #We died. RIP.\n",
        "    print(\"CloudFlare is likely down, Or you somehow facerolled a turn-key two click process hard enough to take a ride on the failboat...\")\n",
        "    print(\"Either way, ENDING the Colab Runtime now...\")\n",
        "    print(\"Give it another try, but if you get this same message every time you try then CloudFlare is dropping the ball.\")\n",
        "    print(\"Keep tabs on the cfstatus page shown above pending resolution of their existential crisis...\")\n",
        "    print(\"Maybe go touch grass while you wait? --FunkEngine\")\n",
        "if needle != '' and not ale_cellar:\n",
        "    #We Ride!\n",
        "    cloudflarelog = open('cloudflare.log', 'w')\n",
        "    cloudflarelog.write(needle)\n",
        "    cloudflarelog.close()\n",
        "    print(\"GO NOW AND RUN THE KCpp CELL TO RUN YOUR MODEL AND STAND UP AN API\")\n",
        "    print(\"Come back up here and click any one of those identical links to open tavern once your model is loaded.\")\n",
        "    os.chdir('/content/TavernAI/')\n",
        "    !!nohup node server.js > /content/drive/MyDrive/TavernAI/console.log 2>&1 &\n",
        "    print(\"FIRE UP YOUR MODEL BELOW!\")\n",
        "    print(\"I'm seriously not going to give you your links YET.\")\n",
        "    print(\"Scroll down and get the AI going first...\")\n",
        "    print(\"THEN you can have your link to TavernAI!\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "# Welcome to the Release Candidate v3.1 extended-beta testing of a weight-reduced low-drag hi-speed version of TavernAI+KCpp\n",
        "\n",
        "# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "## It's Easy!\n",
        "\n",
        "Just press the **Play** button *ABOVE* FIRST to sign into GoogleDrive and fire up TavernAI.\n",
        "\n",
        "Then you head down below, and push KCpp's play button.\n",
        "\n",
        "And **Wait** for your model to load **and** the API to stand up fully.\n",
        "\n",
        "***Then*** you open one of the TavernAI links up above.\n",
        "\n",
        "AS WAS MY INTENTION: THEY NOW **ONLY** SHOW UP __AFTER__ KCpp is finished loading __as well__.\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "### As in:\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "*   You do not __click__ any \"\"\"link.\"\"\" that may be printed to the console by Kobold-Cpp below.\n",
        "*   You don't actually go to the 127.0.0.1 address by clicking it either.\n",
        "*   The link just means the API is running and reachable by TavernAI.\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "### **I cannot stress this enough.**\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "*   YOU DO NOT CLICK THE \"\"\"LINK.\"\"\"\n",
        "*   IT WILL NOT WORK **for** *YOU*.\n",
        "*   Because it's not **FOR** *you*.\n",
        "*   It is *for* __TavernAI__ and TavernAI alone.\n",
        "*   And ONLY that specific TavernAI running __above__!!!\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "If you have a local **node.js** install of TavernAI and actually need just the api URL...\n",
        "\n",
        "**You should be using an API only version of the colab anyway.**\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "# <h1>****This colab will not give tunneled API links!****</h1>\n",
        "\n",
        "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "#### **Keep this page open and check for captchas occasionally.**\n",
        "\n",
        "**Otherwise your AI gets shut down.**\n",
        "\n",
        "*Subscribers to Colab Pro only need to keep the tab open.*\n",
        "\n",
        "***Colab Pro+ subscribers can even close the tab if they want to.***\n",
        "\n",
        "# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\n",
        "\n",
        "Un-hide the cell below to get KCpp started.\n",
        "\n",
        "I look forward to feedback from this __Beta-test__...\n",
        "\n",
        "--FunkEngine\n",
        "# **👷**\n",
        "\n",
        "\n",
        "(Who am I kidding? You're just going to invent more new ways to break Colab Notebooks...)\n",
        "\n",
        "Have at it, then... Do your thing!\n",
        "\n"
      ],
      "metadata": {
        "id": "sDysIMXLmJhs"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "#@title <b>↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ Enter your model below ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ and then click the Play button to start Koboldcpp!</b> { form-width: \"110%\", display-mode: \"form\" }\n",
        "Model = \"https://huggingface.co/TheBloke/Noromaid-13B-v0.3-GGUF/resolve/main/noromaid-13b-v0.3.Q4_K_M.gguf?download=true\" #@param [\"https://huggingface.co/KoboldAI/LLaMA2-13B-Tiefighter-GGUF/resolve/main/LLaMA2-13B-Tiefighter.Q4_K_M.gguf\",\"https://huggingface.co/TheBloke/MythoMax-L2-13B-GGUF/resolve/main/mythomax-l2-13b.Q4_K_M.gguf\",\"https://huggingface.co/TheBloke/ReMM-SLERP-L2-13B-GGUF/resolve/main/remm-slerp-l2-13b.Q4_K_M.gguf\",\"https://huggingface.co/TheBloke/Xwin-LM-13B-v0.2-GGUF/resolve/main/xwin-lm-13b-v0.2.Q4_K_M.gguf\",\"https://huggingface.co/TheBloke/Stheno-L2-13B-GGUF/resolve/main/stheno-l2-13b.Q4_K_M.gguf\",\"https://huggingface.co/TheBloke/MythoMax-L2-Kimiko-v2-13B-GGUF/resolve/main/mythomax-l2-kimiko-v2-13b.Q4_K_M.gguf\",\"https://huggingface.co/TheBloke/airoboros-mistral2.2-7B-GGUF/resolve/main/airoboros-mistral2.2-7b.Q4_K_S.gguf\"]{allow-input: true}\n",
        "bespoke_tunnel = False # @param {type:\"boolean\"}\n",
        "#Layers = 43 #@param [43]{allow-input: true}\n",
        "#ContextSize = 4096 #@param [4096] {allow-input: true}\n",
        "#ForceRebuild = False #@param {type:\"boolean\"}\n",
        "#@markdown Watch for it to say Connect to Endpoint and at that point it has loaded the model, and the API is stood up... You **will** have to scroll up to find your TavernAI links, they print just when KCpp fires up for real and scrolls a nice big wall of text when it does. :)\n",
        "if bespoke_tunnel:\n",
        "    from google.colab import userdata\n",
        "    print(\"Are you a member of the tunnel club?\")\n",
        "    kobotoke = userdata.get('COLABKOBOLDSEC')\n",
        "    if kobotoke  != '':\n",
        "        print(\"Using provided token hashes to plumb into your tunnel infrastructure.\")\n",
        "        if kobotoke != '':\n",
        "            print(\"Looks like you have given us a token for tunneling a port 5000 KoboldAI API out...\")\n",
        "            !!sudo nohup cloudflared tunnel --no-autoupdate run --token $kobotoke > /dev/null 2>&1 &\n",
        "            print(\"Connector is up and running... For a KoboldAI-API on port 5000...\")\n",
        "    print(\"Tunnel plumbed in should be good to go now...\")\n",
        "else:\n",
        "    print(\"Welcome to the faster TavernAI colab!  --FunkEngine\")\n",
        "\n",
        "import os\n",
        "os.chdir('/')\n",
        "!!rm -rf /content/sample_data/\n",
        "from google.colab import output\n",
        "from google.colab import runtime\n",
        "from google.colab import _kernel\n",
        "from IPython.core.display import display, HTML\n",
        "if not os.path.isfile(\"/opt/bin/nvidia-smi\"):\n",
        "    raise RuntimeError(\"⚠️Colab did not give you a GPU!!! With few exceptions this means you have run out of free GPU time for TODAY. You can PAYG for immediate access without actually committing to a Subscription to Colab Pro or Pro+ See: https://colab.research.google.com/signup?utm_source=resource_tab&utm_medium=link&utm_campaign=payg_learn_more with the option ON THE FAR LEFT SIDE being Pay As You Go which for $10 at a time, gets you back onto a GPU __now__ without requiring you to commit to a recurring subscription...⚠️\")\n",
        "    runtime.unassign()\n",
        "os.chdir('/content/')\n",
        "if not os.path.exists('/content/koboldcpp/'):\n",
        "    !!git clone https://github.com/LostRuins/koboldcpp /content/koboldcpp/\n",
        "    os.chdir('/content/koboldcpp/')\n",
        "    kvers = !(cat koboldcpp.py | grep 'KcppVersion = ' | cut -d '\"' -f2)\n",
        "    kvers = kvers[0]\n",
        "    #if ForceRebuild:\n",
        "    #  kvers = \"force_rebuild\"\n",
        "    print(\"Finding prebuilt binary for \", kvers)\n",
        "    !!wget -O dlfile.tmp https://kcppcolab.concedo.workers.dev/?{kvers} && mv dlfile.tmp koboldcpp_cublas.so\n",
        "    !!test -f koboldcpp_cublas.so && echo Prebuilt Binary Exists || echo Prebuilt Binary Does Not Exist\n",
        "    !!test -f koboldcpp_cublas.so && echo Build Skipped || make koboldcpp_cublas LLAMA_CUBLAS=1 LLAMA_PORTABLE=1\n",
        "    if not os.path.exists(\"/content/koboldcpp/koboldcpp_cublas.so\"):\n",
        "        os.link('koboldcpp_cublas.so', 'koboldcpp_cublas.dat')\n",
        "if not os.path.exists('/content/koboldcpp/model.gguf'):\n",
        "    !!aria2c -x 16 -j 8 -o model.gguf --allow-overwrite=true $Model -q\n",
        "print(\"Hey look you're nearly there!\")\n",
        "\n",
        "def beans():\n",
        "    if not bespoke_tunnel:\n",
        "        print(\"LINKS TO YOUR TAVERN SESSION BELOW.\")\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"TavernAI Link:\" + needle)\n",
        "        print(\"LINKS TO YOUR TAVERN SESSION ABOVE.\")\n",
        "    print(\"If you didn't get links, CloudFlare is probably down at this time. Or you're using the ale_cellar secret tunnel.\")\n",
        "    return\n",
        "\n",
        "\n",
        "os.chdir('/content/koboldcpp/')\n",
        "beans()\n",
        "!!python3 koboldcpp.py model.gguf 5000 --contextsize 4096 --usecublas 0 --gpulayers 64 --multiuser --quiet\n"
      ],
      "metadata": {
        "id": "zxoG8UFPmHzc"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}
